import { _decorator, color, director, System, Vec3, v3 } from 'cc';
import { lobby } from './UIRoot';
import { BaseManager } from '../../scripts/libs/rxjs/cc3/BaseManager';
import { ReactiveProperty } from '../../scripts/libs/rxjs/cc3/ReactiveProperty';
import { LobbySceneCanvas } from './LobbySceneCanvas';
import { MergeASAP } from '../../scripts/libs/rxjs/cc3/Merge';
import { Subscription } from 'rxjs';
import { FrontTipPanel } from './ui/FrontTipPanel/FrontTipPanel';
import { FlowStatus } from './Enums';
import { gm } from '../../scripts/managers/GameManager';
import { GameKey } from '../../scripts/managers/SubgameConfig';
import { am } from '../../scripts/managers/AudioManager';
import { nullifySubscription } from '../../scripts/libs/rxjs/utils';
import { rxccconfig } from '../../scripts/libs/rxjs/cc3/RxCCConfig';
import { ReactiveCommand } from '../../scripts/libs/rxjs/cc3/ReactiveCommand';
import { EventTouch } from 'cc';
import { ReactiveSet } from '../../scripts/libs/rxjs/cc3/ReactiveSet';
import { udm } from '../../scripts/managers/UserDataManager';
import { DevConfig } from '../../scripts/managers/DevConfig';
import { ResourceHelper } from './ResourceHelper';
import { view } from 'cc';
import { linear } from '../../scripts/libs/utils/math';
// import { Proto_echo } from '../../scripts/proto/Proto_echo';
const { ccclass, property } = _decorator;

@ccclass('LobbyManager')
class LobbyManager extends BaseManager {

    public static instance: LobbyManager;
    static ID = 'lobby_system';
    get logColorOverride() { return color().fromHEX('#223344') };

    static registerSystem() {
        director.unregisterSystem(director.getSystem(LobbyManager.ID));
        director.registerSystem(LobbyManager.ID, lm, System.Priority.MEDIUM);
        lm.init();
    }

    static unregisterSystem() {
        lm.destroy();
        director.unregisterSystem(director.getSystem(LobbyManager.ID));
    }

    // ui flow
    flowStatus = ReactiveProperty.Create(FlowStatus.Empty);
    loadingEnabled = ReactiveProperty.Create(null);
    frontTipEnabled = ReactiveProperty.Create(false);
    frontTipReady = ReactiveProperty.Create(false);
    loadingAssets = ReactiveProperty.Create(true);
    hotupdating = ReactiveProperty.Create(false);

    gameWinPanelOpened = ReactiveProperty.Create(false);
    gameLosePanelOpened = ReactiveProperty.Create(false);
    settingsPanelOpened = ReactiveProperty.Create(false);
    pausePanelOpened = ReactiveProperty.Create(false);

    loseLifeTipPanelOpened = ReactiveProperty.Create(false);
    itemUnlockPanelOpened = ReactiveProperty.Create(false);
    shopPanelOpened = ReactiveProperty.Create(false);
    dailyTaskPanelOpened = ReactiveProperty.Create(false);
    luckyWheelPanelOpened = ReactiveProperty.Create(false);
    featureUnlockPanelOpened = ReactiveProperty.Create(false);

    customLoadingReasons = ReactiveSet.Create<string>([]);

    lobbySceneCanvas: LobbySceneCanvas = null;
    uiRoot: lobby.UIRoot = null;

    // fronttip
    frontTip: FrontTipPanel = null;

    _sub_buttonClick: Subscription = null;

    touchGame = ReactiveCommand.Create<EventTouch>();

    useObserves() {
        return [
            MergeASAP(
                this.loadingAssets, this.hotupdating, this.customLoadingReasons /*, this.wsConnected*/
            ).subscribe(_ => {
                let hasReasons = this.customLoadingReasons.size > 0;
                this.loadingEnabled.value = [this.loadingAssets.value, this.hotupdating.value/*, !this.wsConnected.value*/, hasReasons].some(_ => _);
            }),
            gm.loadingAssets.subscribe(_ => { this.loadingAssets.value = _ }),
            gm.curSubgame.subscribe(_ => {
                if (_ == null) return;
                nullifySubscription.call(this, '_sub_buttonClick');
                if (_ == GameKey.lobby) {

                    this._sub_buttonClick = rxccconfig.buttonWillClickCommand.subscribe(_ => {
                        if (_.node.name.endsWith('[silent]')) {
                        } else if (_.node.name.startsWith('back') || _.node.name.startsWith('close')) {
                            am.play.execute('ab_lobby/Audio/sfx/ButtonClick');
                        } else {
                            am.play.execute('ab_lobby/Audio/sfx/ButtonClick');
                        }
                    });

                    // 换成别的Status，比如可以直接直接进Game

                    lm.customLoadingReasons.add('load_stage');

                    // 检查合法性
                    if (udm.stageNum.value > DevConfig.STAGE_NUM_MAX) {
                        udm.stageNum.value = DevConfig.STAGE_NUM_MAX;
                    }

                    ResourceHelper.LoadStageAssets(udm.stageNum.value).subscribe(stageInfo => {
                        if (stageInfo != null) {
                            lm.customLoadingReasons.delete('load_stage');
                            if (stageInfo.stageId != null && stageInfo.stageId != udm.stageNum.value) {
                                this.warn('StageId in json is not match with stageId in file name.');
                                return;
                            }
                            stageInfo.stageId = udm.stageNum.value;
                            gm.stageInfo.value = stageInfo;

                            if (udm.stageNum.value > DevConfig.DIRECT_START_LESSEQUAL_STAGE_NUM) {
                                this.flowStatus.value = FlowStatus.Lobby;
                            } else {
                                if (gm.editEnabled.value) {
                                    lm.flowStatus.value = FlowStatus.Lobby; //FlowStatus.EditorGame;
                                } else {
                                    let curHeartCount = udm.getHeartCount();
                                    if (udm.getRemainMsToOverInfHeart() > 0 || curHeartCount > 0) {
                                        lm.flowStatus.value = FlowStatus.Game;
                                    } else {
                                        this.flowStatus.value = FlowStatus.Lobby;
                                    }
                                }
                            }

                            // 上一次欠的开关卡宝箱 TODO:

                        } else {
                            lm.customLoadingReasons.delete('load_stage');

                            if (gm.editEnabled.value) {
                                lm.flowStatus.value = FlowStatus.Lobby;
                            } else {
                                this.flowStatus.value = FlowStatus.Lobby;
                            }
                        }
                    });

                    if (gm.editEnabled.value) {
                    } else {
                        am.bgm.value = 'ab_lobby/Audio/bgm/music';
                    }

                } else {
                    this.flowStatus.value = FlowStatus.Empty;
                    am.bgm.value = null;
                    // 每个游戏的按钮声音都可以不同
                    this._sub_buttonClick = rxccconfig.buttonWillClickCommand.subscribe(_ => {
                        if (_.node.name.endsWith('[silent]')) {
                        } else if (_.node.name.startsWith('back') || _.node.name.startsWith('close')) {
                            am.play.execute('ab_lobby/Audio/sfx/ButtonClick');
                        } else {
                            am.play.execute('ab_lobby/Audio/sfx/ButtonClick');
                        }
                    });
                }
            }),


            this.settingsPanelOpened.subscribe(_ => _ ? gm.pauseReason.add('setting_panel_opened') : gm.pauseReason.delete('setting_panel_opened')),
            this.pausePanelOpened.subscribe(_ => _ ? gm.pauseReason.add('pause_panel_opened') : gm.pauseReason.delete('pause_panel_opened')),
            this.featureUnlockPanelOpened.subscribe(_ => _ ? gm.pauseReason.add('feature_unlock_panel_opened') : gm.pauseReason.delete('feature_unlock_panel_opened')),
            this.gameWinPanelOpened.subscribe(_ => _ ? gm.pauseReason.add('game_win_panel_opened') : gm.pauseReason.delete('game_win_panel_opened')),
            this.gameLosePanelOpened.subscribe(_ => _ ? gm.pauseReason.add('game_lose_panel_opened') : gm.pauseReason.delete('game_lose_panel_opened')),
            this.gameWinPanelOpened.subscribe(_ => _ ? gm.bgmFadeReason.add('game_win_panel_opened') : gm.bgmFadeReason.delete('game_win_panel_opened')),
            this.gameLosePanelOpened.subscribe(_ => _ ? gm.bgmFadeReason.add('game_lose_panel_opened') : gm.bgmFadeReason.delete('game_lose_panel_opened')),
        ]
    }

    // 封装一个简便的信息弹出
    frontTipShow(message: string, interval: number = 2) {
        if (this.frontTip != null) return this.frontTip.show(message, interval).subscribe();
    }

    getAdaptiveScale() {
        let height = view.getVisibleSize().height;
        let scale = linear(1650, 2400, .7, 1, height);
        return scale;
    }

    getAdaptiveScaleV3() {
        return v3(Vec3.ONE).multiplyScalar(this.getAdaptiveScale());
    }
}

globalThis.LobbyManager = LobbyManager;

export const lm = LobbyManager.instance = new LobbyManager();
